﻿package core.ui.util
{
    import TransformTool.as$324.*;
    import core.enum.*;
    import core.ui.controls.*;
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;

    public class TransformTool extends Sprite
    {
        private var toolInvertedMatrix:Matrix;
        private var innerRegistration:Point;
        private var targetBounds:Rectangle;
        private var mouseLoc:Point;
        private var mouseOffset:Point;
        private var innerMouseLoc:Point;
        private var interactionStart:Point;
        private var innerInteractionStart:Point;
        private var interactionStartAngle:Number = 0;
        private var interactionStartMatrix:Matrix;
        public var target:DisplayObject;
        public var toolMatrix:Matrix;
        public var _globalMatrix:Matrix;
        public var registration:Point;
        public var shifted:Boolean = false;
        public var boundsTopLeft:Point;
        public var boundsTop:Point;
        public var boundsTopRight:Point;
        public var boundsRight:Point;
        public var boundsBottomRight:Point;
        public var boundsBottom:Point;
        public var boundsBottomLeft:Point;
        public var boundsLeft:Point;
        public var boundsCenter:Point;
        public var currentControl:TransformToolControl;
        var p:Tuyitu;
        var editmask:Boolean;
        var virginMatrix:Matrix;
        var virginGlobal:Matrix;
        public static const CONTROL_TRANSFORM_TOOL:String = "controlTransformTool";
        public static const TRANSFORM_TOOL:String = "transformTool";
        public static const CONTROL_INIT:String = "controlInit";
        public static const CONTROL_MOVE:String = "controlMove";

        public function TransformTool(param1:Tuyitu)
        {
            this.toolInvertedMatrix = new Matrix();
            this.innerRegistration = new Point();
            this.targetBounds = new Rectangle();
            this.mouseLoc = new Point();
            this.mouseOffset = new Point();
            this.innerMouseLoc = new Point();
            this.interactionStart = new Point();
            this.innerInteractionStart = new Point();
            this.interactionStartMatrix = new Matrix();
            this.toolMatrix = new Matrix();
            this._globalMatrix = new Matrix();
            this.registration = new Point();
            this.boundsTopLeft = new Point();
            this.boundsTop = new Point();
            this.boundsTopRight = new Point();
            this.boundsRight = new Point();
            this.boundsBottomRight = new Point();
            this.boundsBottom = new Point();
            this.boundsBottomLeft = new Point();
            this.boundsLeft = new Point();
            this.boundsCenter = new Point();
            this.p = param1;
            param1.addChild(this);
            param1.SetModal(this, false);
            param1.canvas.history.Prepare(Action.Transform);
            this.editmask = param1.canvas.layer.editMask;
            param1.canvas.layer.editMask = false;
            this.target = param1.canvas.layer.SetBitmapCutEditMode(param1.canvas.selection, Boolean(param1.canvas.document.anr == 0 && !param1.canvas.document.transparent), true);
            param1.canvas.RemoveSelection();
            this.virginMatrix = this.target.transform.matrix.clone();
            this.virginGlobal = param1.canvas.document.transform.concatenatedMatrix.clone();
            this.virginGlobal.tx = this.virginGlobal.tx + param1.canvas.layer.offset.x * param1.canvas.document.scaleX;
            this.virginGlobal.ty = this.virginGlobal.ty + param1.canvas.layer.offset.y * param1.canvas.document.scaleY;
            this.updateMatrix(this.virginGlobal);
            this.setNewRegistation();
            this.createControls();
            stage.addEventListener(KeyboardEvent.KEY_UP, this.KeyUP, false, 0, true);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, this.KeyDown, false, 0, true);
            param1.modal.addEventListener(MouseEvent.MOUSE_DOWN, this.ClickOutside, false, 0, true);
            param1.modal.addEventListener(MouseEvent.MOUSE_OVER, this.ResetMouse, false, 0, true);
            return;
        }// end function

        public function get globalMatrix() : Matrix
        {
            var _loc_1:* = this.toolMatrix.clone();
            _loc_1.concat(transform.concatenatedMatrix);
            return _loc_1;
        }// end function

        public function set globalMatrix(KeyDown:Matrix) : void
        {
            this.updateMatrix(KeyDown);
            this.updateRegistration();
            dispatchEvent(new Event(TRANSFORM_TOOL));
            return;
        }// end function

        private function ResetMouse(event:Event) : void
        {
            this.p.cursor.Set(ToolType.None);
            return;
        }// end function

        private function KeyUP(event:KeyboardEvent) : void
        {
            if (event.keyCode == 13)
            {
                this.OK();
            }
            else if (event.keyCode == 27)
            {
                this.Cancel();
            }
            else if (event.keyCode == 16)
            {
                this.shifted = false;
            }
            return;
        }// end function

        private function KeyDown(event:KeyboardEvent) : void
        {
            if (event.keyCode == 16 && !this.shifted)
            {
                this.shifted = true;
            }
            return;
        }// end function

        public function ClickOutside(event:MouseEvent) : void
        {
            new ConfirmDialog(this.p, U.RM("rm_apply_changes"), this.OK, this.Cancel);
            return;
        }// end function

        public function OK(event:Event = null) : void
        {
            this.p.canvas.history.Commit();
            var _loc_2:* = new Bitmap(new BitmapData(this.p.canvas.dw, this.p.canvas.dh, true, 16777215));
            _loc_2.bitmapData.draw(this.p.canvas.layer.holder);
            this.p.canvas.layer.holder.removeChild(this.target);
            if (this.p.canvas.layer.bitmap.bitmapData != null)
            {
                this.p.canvas.layer.bitmap.bitmapData.dispose();
                this.p.canvas.layer.bitmap.bitmapData = null;
            }
            this.p.canvas.layer.holder.addChild(_loc_2);
            this.p.canvas.layer.RemoveBitmapEditMode();
            this.p.canvas.UpdateAfterEdit();
            this.Close();
            return;
        }// end function

        public function Cancel(event:Event = null) : void
        {
            this.p.canvas.SetSelection(this.p.canvas.history.prepare.args[1]);
            this.target.transform.matrix = this.virginMatrix;
            this.p.canvas.layer.RemoveBitmapEditMode();
            this.p.canvas.UpdateAfterEdit();
            this.Close();
            return;
        }// end function

        public function Close() : void
        {
            this.p.modal.removeEventListener(MouseEvent.MOUSE_DOWN, this.ClickOutside, false);
            this.p.modal.removeEventListener(MouseEvent.MOUSE_OVER, this.ResetMouse, false);
            stage.removeEventListener(KeyboardEvent.KEY_UP, this.KeyUP, false);
            stage.removeEventListener(KeyboardEvent.KEY_DOWN, this.KeyDown, false);
            this.p.canvas.layer.editMask = this.editmask;
            this.p.removeChild(this);
            this.p.RemoveModal();
            return;
        }// end function

        public function apply() : void
        {
            var _loc_1:* = this.toolMatrix.clone();
            _loc_1.concat(transform.concatenatedMatrix);
            var _loc_2:* = this.p.canvas.document.transform.concatenatedMatrix.clone();
            _loc_2.tx = _loc_2.tx + this.p.canvas.layer.x * this.p.canvas.document.scaleX;
            _loc_2.ty = _loc_2.ty + this.p.canvas.layer.y * this.p.canvas.document.scaleY;
            _loc_2.invert();
            _loc_1.concat(_loc_2);
            this.target.transform.matrix = _loc_1;
            return;
        }// end function

        private function createControls() : void
        {
            this.addToolControl(this, new TransformToolRotateControl(this.p, this, "rtl", this.rotationInteraction, "boundsTopLeft"));
            this.addToolControl(this, new TransformToolRotateControl(this.p, this, "rtr", this.rotationInteraction, "boundsTopRight"));
            this.addToolControl(this, new TransformToolRotateControl(this.p, this, "rbr", this.rotationInteraction, "boundsBottomRight"));
            this.addToolControl(this, new TransformToolRotateControl(this.p, this, "rbl", this.rotationInteraction, "boundsBottomLeft"));
            this.addToolControl(this, new TransformToolMoveShape(this.p, this, "move", this.moveInteraction));
            this.addToolControl(this, new TransformToolRegistrationControl(this.p, this, "r", this.registrationInteraction, "registration"));
            this.addToolControl(this, new TransformToolScaleControl(this.p, this, "st", this.scaleYInteraction, "boundsTop"));
            this.addToolControl(this, new TransformToolScaleControl(this.p, this, "sr", this.scaleXInteraction, "boundsRight"));
            this.addToolControl(this, new TransformToolScaleControl(this.p, this, "sb", this.scaleYInteraction, "boundsBottom"));
            this.addToolControl(this, new TransformToolScaleControl(this.p, this, "sl", this.scaleXInteraction, "boundsLeft"));
            this.addToolControl(this, new TransformToolScaleControl(this.p, this, "stl", this.scaleBothInteraction, "boundsTopLeft"));
            this.addToolControl(this, new TransformToolScaleControl(this.p, this, "str", this.scaleBothInteraction, "boundsTopRight"));
            this.addToolControl(this, new TransformToolScaleControl(this.p, this, "sbr", this.scaleBothInteraction, "boundsBottomRight"));
            this.addToolControl(this, new TransformToolScaleControl(this.p, this, "sbl", this.scaleBothInteraction, "boundsBottomLeft"));
            return;
        }// end function

        private function addToolControl(KeyDown:Sprite, KeyDown:TransformToolControl) : void
        {
            KeyDown.addEventListener(MouseEvent.MOUSE_DOWN, this.startInteractionHandler, false, 1, true);
            KeyDown.addChild(KeyDown);
            KeyDown.dispatchEvent(new Event(CONTROL_INIT));
            return;
        }// end function

        private function startInteractionHandler(event:MouseEvent) : void
        {
            this.currentControl = event.currentTarget as TransformToolControl;
            this.updateMatrix();
            this.apply();
            this.mouseOffset = this.currentControl && this.currentControl.referencePoint ? (this.currentControl.referencePoint.subtract(new Point(mouseX, mouseY))) : (new Point(0, 0));
            this.updateMouse();
            this.interactionStart = this.mouseLoc.clone();
            this.innerInteractionStart = this.innerMouseLoc.clone();
            this.interactionStartMatrix = this.toolMatrix.clone();
            this.interactionStartAngle = this.distortAngle();
            this.p.cursor.freeze = true;
            stage.addEventListener(MouseEvent.MOUSE_MOVE, this.interactionHandler, false, 1, true);
            stage.addEventListener(MouseEvent.MOUSE_UP, this.endInteractionHandler, false, 1, false);
            return;
        }// end function

        private function interactionHandler(event:MouseEvent) : void
        {
            this.updateMouse();
            this.toolMatrix = this.interactionStartMatrix.clone();
            dispatchEvent(new Event(CONTROL_MOVE));
            dispatchEvent(new Event(CONTROL_TRANSFORM_TOOL));
            this.apply();
            event.updateAfterEvent();
            return;
        }// end function

        private function endInteractionHandler(event:MouseEvent) : void
        {
            this.apply();
            this.p.cursor.freeze = false;
            if (event.target != this.currentControl)
            {
                this.p.cursor.Set(ToolType.None);
            }
            stage.removeEventListener(MouseEvent.MOUSE_MOVE, this.interactionHandler);
            stage.removeEventListener(MouseEvent.MOUSE_UP, this.endInteractionHandler);
            this.currentControl = null;
            return;
        }// end function

        public function moveInteraction() : void
        {
            var _loc_1:* = this.mouseLoc.subtract(this.interactionStart);
            this.toolMatrix.tx = this.toolMatrix.tx + _loc_1.x;
            this.toolMatrix.ty = this.toolMatrix.ty + _loc_1.y;
            this.updateRegistration();
            this.completeInteraction();
            return;
        }// end function

        public function registrationInteraction() : void
        {
            this.registration.x = this.mouseLoc.x;
            this.registration.y = this.mouseLoc.y;
            this.innerRegistration = this.toolInvertedMatrix.transformPoint(this.registration);
            this.completeInteraction();
            return;
        }// end function

        public function rotationInteraction() : void
        {
            var _loc_1:* = transform.concatenatedMatrix;
            var _loc_2:* = _loc_1.clone();
            _loc_2.invert();
            this.toolMatrix.concat(_loc_1);
            var _loc_3:* = this.distortAngle() - this.interactionStartAngle;
            if (this.shifted)
            {
                if (_loc_3 > Math.PI)
                {
                    _loc_3 = _loc_3 - Math.PI * 2;
                }
                else if (_loc_3 < -Math.PI)
                {
                    _loc_3 = _loc_3 + Math.PI * 2;
                }
                _loc_3 = Math.round(_loc_3 / (Math.PI / 4)) * (Math.PI / 4);
            }
            this.toolMatrix.rotate(_loc_3);
            this.toolMatrix.concat(_loc_2);
            this.completeInteraction(true);
            return;
        }// end function

        public function scaleXInteraction() : void
        {
            trace("innerMouseLoc=" + this.innerMouseLoc);
            trace("innerInteractionStart=" + this.innerInteractionStart);
            trace("innerRegistration=" + this.innerRegistration);
            var _loc_1:* = this.distortOffset(new Point(this.innerMouseLoc.x, this.innerInteractionStart.y), this.innerInteractionStart.x - this.innerRegistration.x);
            trace("this.toolMatrix.a1=" + this.toolMatrix.a);
            this.toolMatrix.a = this.toolMatrix.a + _loc_1.x;
            this.toolMatrix.b = this.toolMatrix.b + _loc_1.y;
            trace("this.toolMatrix.a2=" + this.toolMatrix.a);
            this.completeInteraction(true);
            trace("----------------------------------------------------");
            return;
        }// end function

        public function scaleYInteraction() : void
        {
            var _loc_1:* = this.distortOffset(new Point(this.innerInteractionStart.x, this.innerMouseLoc.y), this.innerInteractionStart.y - this.innerRegistration.y);
            this.toolMatrix.c = this.toolMatrix.c + _loc_1.x;
            this.toolMatrix.d = this.toolMatrix.d + _loc_1.y;
            this.completeInteraction(true);
            return;
        }// end function

        public function scaleBothInteraction() : void
        {
            var _loc_1:Point = null;
            var _loc_2:Point = null;
            var _loc_3:* = undefined;
            var _loc_4:* = undefined;
            var _loc_5:* = this.innerMouseLoc.clone();
            if (this.shifted)
            {
                _loc_1 = this.innerMouseLoc.subtract(this.innerInteractionStart);
                _loc_2 = this.innerInteractionStart.subtract(this.innerRegistration);
                _loc_3 = _loc_2.x ? (_loc_1.x / _loc_2.x) : (0);
                _loc_4 = _loc_2.y ? (_loc_1.y / _loc_2.y) : (0);
                if (_loc_3 > _loc_4)
                {
                    _loc_5.x = this.innerInteractionStart.x + _loc_2.x * _loc_4;
                }
                else
                {
                    _loc_5.y = this.innerInteractionStart.y + _loc_2.y * _loc_3;
                }
            }
            var _loc_6:* = this.distortOffset(new Point(_loc_5.x, this.innerInteractionStart.y), this.innerInteractionStart.x - this.innerRegistration.x);
            var _loc_7:* = this.distortOffset(new Point(this.innerInteractionStart.x, _loc_5.y), this.innerInteractionStart.y - this.innerRegistration.y);
            this.toolMatrix.a = this.toolMatrix.a + _loc_6.x;
            this.toolMatrix.b = this.toolMatrix.b + _loc_6.y;
            this.toolMatrix.c = this.toolMatrix.c + _loc_7.x;
            this.toolMatrix.d = this.toolMatrix.d + _loc_7.y;
            this.completeInteraction(true);
            return;
        }// end function

        private function distortOffset(CONTROL_INIT:Point, CONTROL_INIT:Number) : Point
        {
            var _loc_3:* = CONTROL_INIT ? (this.targetBounds.width / CONTROL_INIT) : (0);
            var _loc_4:* = CONTROL_INIT ? (this.targetBounds.height / CONTROL_INIT) : (0);
            trace("_local3=" + _loc_3, "_local4=" + _loc_4);
            CONTROL_INIT = this.interactionStartMatrix.transformPoint(CONTROL_INIT).subtract(this.interactionStart);
            CONTROL_INIT.x = CONTROL_INIT.x * (this.targetBounds.width ? (_loc_3 / this.targetBounds.width) : (0));
            CONTROL_INIT.y = CONTROL_INIT.y * (this.targetBounds.height ? (_loc_4 / this.targetBounds.height) : (0));
            trace("_arg1=" + CONTROL_INIT);
            return CONTROL_INIT;
        }// end function

        private function completeInteraction(KeyDown:Boolean = false) : void
        {
            var _loc_2:Point = null;
            if (KeyDown)
            {
                _loc_2 = this.registration.subtract(this.toolMatrix.transformPoint(this.innerRegistration));
                this.toolMatrix.tx = this.toolMatrix.tx + _loc_2.x;
                this.toolMatrix.ty = this.toolMatrix.ty + _loc_2.y;
            }
            this.updateBounds();
            return;
        }// end function

        private function distortAngle() : Number
        {
            var _loc_1:* = transform.concatenatedMatrix;
            var _loc_2:* = _loc_1.transformPoint(this.mouseLoc);
            var _loc_3:* = _loc_1.transformPoint(this.registration);
            var _loc_4:* = _loc_2.subtract(_loc_3);
            return Math.atan2(_loc_4.y, _loc_4.x);
        }// end function

        private function updateMouse() : void
        {
            this.mouseLoc = new Point(mouseX, mouseY).add(this.mouseOffset);
            this.innerMouseLoc = this.toolInvertedMatrix.transformPoint(this.mouseLoc);
            return;
        }// end function

        private function updateMatrix(KeyDown:Matrix = null) : void
        {
            if (KeyDown)
            {
                this.toolMatrix = KeyDown.clone();
            }
            this.toolInvertedMatrix = this.toolMatrix.clone();
            this.toolInvertedMatrix.invert();
            this.updateBounds();
            return;
        }// end function

        private function updateBounds() : void
        {
            this.targetBounds = this.target.getBounds(this.target);
            trace("this.targetBounds=" + this.targetBounds);
            this.boundsTopLeft = this.toolMatrix.transformPoint(new Point(this.targetBounds.left, this.targetBounds.top));
            this.boundsTopRight = this.toolMatrix.transformPoint(new Point(this.targetBounds.right, this.targetBounds.top));
            this.boundsBottomRight = this.toolMatrix.transformPoint(new Point(this.targetBounds.right, this.targetBounds.bottom));
            this.boundsBottomLeft = this.toolMatrix.transformPoint(new Point(this.targetBounds.left, this.targetBounds.bottom));
            this.boundsTop = Point.interpolate(this.boundsTopLeft, this.boundsTopRight, 0.5);
            this.boundsRight = Point.interpolate(this.boundsTopRight, this.boundsBottomRight, 0.5);
            this.boundsBottom = Point.interpolate(this.boundsBottomRight, this.boundsBottomLeft, 0.5);
            this.boundsLeft = Point.interpolate(this.boundsBottomLeft, this.boundsTopLeft, 0.5);
            this.boundsCenter = Point.interpolate(this.boundsTopLeft, this.boundsBottomRight, 0.5);
            return;
        }// end function

        private function updateRegistration() : void
        {
            this.registration = this.toolMatrix.transformPoint(this.innerRegistration);
            return;
        }// end function

        private function setNewRegistation() : void
        {
            this.innerRegistration = new Point(this.target.width / 2, this.target.height / 2);
            this.updateRegistration();
            return;
        }// end function

        public function draw() : void
        {
            this.updateMatrix();
            dispatchEvent(new Event(TRANSFORM_TOOL));
            return;
        }// end function

    }
}
